package gbench.mydata.driver;

import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import gbench.common.tree.LittleTree;
import gbench.common.tree.LittleTree.IRecord;
import gbench.mydata.driver.core.codecs.Codecs;
import gbench.mydata.driver.core.data.DataFile;
import gbench.mydata.driver.core.data.IDataFile;
import gbench.mydata.driver.core.jdbc.AbstractResultSet;

/**
 * 结果集合结构
 * 
 * @author gbench
 *
 */
public class MyDataResultSet extends AbstractResultSet {
    /**
     * 数据集对象
     */
    public MyDataResultSet(final String sql, final IRecord connectionInfo) {
        super(connectionInfo);
        // System.err.println(connectionInfo);

        // file 的 名称结构示例 ?C%3A%2FUsers%2Fgbench%2FDesktop%2Ftmp%2Fbook.xlsx
        final var file = connectionInfo.str("file").strip(); // 提取 excel 文件
        final var sheet = connectionInfo.str("sheet").strip(); // 提取表单名称
        final var excelfile = new Codecs().decode(file.substring(file.indexOf("?") + 1)).strip(); // 文件路径解析
        // System.err.println(excelfile);

        this.dataFile = new DataFile(excelfile); // 解析数据文件

        // 数字被识别为 表单索引，文字 视为 表单名称
        final var shtId = sheet.matches("\\d+") ? Integer.parseInt(sheet) : -1; // 分析 sheet 究竟是数字还是文字。
        final var strmatrix = shtId >= 0 ? this.dataFile.get(shtId) : this.dataFile.get(sheet); // 生成表单矩阵

        this.initialize(strmatrix.mapByRow(IRecord::REC).collect(Collectors.toList())); // 行记录集合
    }

    /**
     * 构造函数
     * 
     * @param dataIterable 可遍历数据集合
     */
    public MyDataResultSet(final Iterable<IRecord> dataIterable) {
        this(LittleTree.iterable2list(dataIterable));
    }

    /**
     * 构造函数
     * 
     * @param dataIterable 可遍历数据集合
     */
    public MyDataResultSet(final List<IRecord> dataset) {
        super(IRecord.REC());
        this.initialize(dataset);
    }

    @Override
    public ResultSetMetaData getMetaData() throws SQLException {
        return new MyDataResultSetMetaData(this.dataset.get(0));
    }

    @Override
    public void close() throws SQLException {

        if (!this.isClosed()) {
            super.close(); // 调用父类的关闭, 设置 is_closed 为 true
            if (this.dataFile != null) {
                this.dataFile.close();
            } // if
        } // if
    }

    /**
     * 初始化
     * 
     * @param dataset 结果集合
     */
    public void initialize(final List<IRecord> dataset) {
        if (dataset != null) { // dataset 数据集
            this.dataset(dataset);
            this.metadata(this.dataset().size() > 0 ? this.dataset().get(0) : null); // 提取第一行记录作metadata
        } // if
        this.reset(-1); // 重置索引
    }

    /**
     * 结果集合的归并器
     * 
     * @return 结果集合 归并器 [rec]->MyDataResultSet
     */
    public static Collector<IRecord, ?, MyDataResultSet> mdrsclc() {
        return Collector.of((Supplier<List<IRecord>>) ArrayList::new, List::add, (left, right) -> {
            left.addAll(right);
            return left;
        }, MyDataResultSet::new);
    }

    private IDataFile dataFile;
}
